/**
 * Canvas 事件处理器
 * 处理鼠标事件、滚动事件等
 * 文件行数: < 500 行
 */

import type { Employee, Shift, ScheduleContext } from '../../types'
import type { CanvasDrawer } from './CanvasDrawer'

export class EventHandler {
  private canvas: HTMLCanvasElement
  private drawer: CanvasDrawer
  private context: ScheduleContext
  private employees: Employee[]
  private dates: string[]
  private shifts: Shift[]

  private isDraggingHScroll = false
  private isDraggingVScroll = false
  private dragStartX = 0
  private dragStartY = 0
  private dragStartScrollX = 0
  private dragStartScrollY = 0

  constructor(
    canvas: HTMLCanvasElement,
    drawer: CanvasDrawer,
    context: ScheduleContext,
    employees: Employee[],
    dates: string[],
    shifts: Shift[]
  ) {
    this.canvas = canvas
    this.drawer = drawer
    this.context = context
    this.employees = employees
    this.dates = dates
    this.shifts = shifts

    this.attachEvents()
  }

  updateData(employees: Employee[], dates: string[], shifts: Shift[]) {
    this.employees = employees
    this.dates = dates
    this.shifts = shifts
  }

  private attachEvents() {
    this.canvas.addEventListener('click', this.handleClick)
    this.canvas.addEventListener('contextmenu', this.handleContextMenu)
    this.canvas.addEventListener('mousedown', this.handleMouseDown)
    this.canvas.addEventListener('mousemove', this.handleMouseMove)
    this.canvas.addEventListener('mouseup', this.handleMouseUp)
    this.canvas.addEventListener('mouseleave', this.handleMouseLeave)
    this.canvas.addEventListener('wheel', this.handleWheel)
  }

  destroy() {
    this.canvas.removeEventListener('click', this.handleClick)
    this.canvas.removeEventListener('contextmenu', this.handleContextMenu)
    this.canvas.removeEventListener('mousedown', this.handleMouseDown)
    this.canvas.removeEventListener('mousemove', this.handleMouseMove)
    this.canvas.removeEventListener('mouseup', this.handleMouseUp)
    this.canvas.removeEventListener('mouseleave', this.handleMouseLeave)
    this.canvas.removeEventListener('wheel', this.handleWheel)
  }

  private getMousePosition(e: MouseEvent): { x: number; y: number } {
    const rect = this.canvas.getBoundingClientRect()
    return {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top,
    }
  }

  private handleClick = (e: MouseEvent) => {
    const pos = this.getMousePosition(e)
    const cell = this.drawer.getCellAt(pos.x, pos.y)

    console.log('🖱️ Canvas 点击:', { pos, cell })

    if (cell) {
      const employee = this.employees[cell.row]
      const date = this.dates[cell.col]

      if (employee && date) {
        console.log('✅ 发送 cell:click 事件:', { employeeId: employee.id, date })
        this.context.emit('cell:click', {
          employeeId: employee.id,
          date,
        })
      }
    }
  }

  private handleContextMenu = (e: MouseEvent) => {
    e.preventDefault()
    const pos = this.getMousePosition(e)
    const cell = this.drawer.getCellAt(pos.x, pos.y)

    console.log('🖱️ Canvas 右键:', { pos, cell })

    if (cell) {
      const employee = this.employees[cell.row]
      const date = this.dates[cell.col]

      if (employee && date) {
        console.log('✅ 发送 cell:contextMenu 事件:', { employeeId: employee.id, date })
        this.context.emit('cell:contextMenu', {
          employeeId: employee.id,
          date,
          x: e.clientX,
          y: e.clientY,
        })
      }
    }
  }

  private handleMouseDown = (e: MouseEvent) => {
    const pos = this.getMousePosition(e)
    const scrollbar = this.drawer.getScrollbar()

    // 检查是否点击了水平滚动条
    const hbar = scrollbar.horizontal
    if (
      hbar.visible &&
      pos.x >= hbar.x + hbar.thumbX &&
      pos.x <= hbar.x + hbar.thumbX + hbar.thumbWidth &&
      pos.y >= hbar.y &&
      pos.y <= hbar.y + hbar.height
    ) {
      this.isDraggingHScroll = true
      this.dragStartX = pos.x
      this.dragStartScrollX = this.drawer.getViewport().scrollX
      hbar.isDragging = true
      this.drawer.draw()
      return
    }

    // 检查是否点击了垂直滚动条
    const vbar = scrollbar.vertical
    if (
      vbar.visible &&
      pos.x >= vbar.x &&
      pos.x <= vbar.x + vbar.width &&
      pos.y >= vbar.y + vbar.thumbY &&
      pos.y <= vbar.y + vbar.thumbY + vbar.thumbHeight
    ) {
      this.isDraggingVScroll = true
      this.dragStartY = pos.y
      this.dragStartScrollY = this.drawer.getViewport().scrollY
      vbar.isDragging = true
      this.drawer.draw()
      return
    }
  }

  private handleMouseMove = (e: MouseEvent) => {
    const pos = this.getMousePosition(e)

    if (this.isDraggingHScroll) {
      const deltaX = pos.x - this.dragStartX
      const scrollbar = this.drawer.getScrollbar().horizontal
      const contentWidth = this.drawer.getTotalContentWidth()
      const viewWidth = this.drawer.getCanvasWidth() - 150 - 12
      const maxScroll = Math.max(0, contentWidth - viewWidth)

      const maxThumbX = scrollbar.width - scrollbar.thumbWidth
      const scrollRatio = maxScroll / maxThumbX
      const newScrollX = Math.max(
        0,
        Math.min(maxScroll, this.dragStartScrollX + deltaX * scrollRatio)
      )

      const viewport = this.drawer.getViewport()
      viewport.scrollX = newScrollX
      this.drawer.setViewport(viewport)
      this.drawer.draw()

      // 发布滚动事件
      this.context.emit('canvas:scroll', {
        scrollX: viewport.scrollX,
        scrollY: viewport.scrollY,
      })
    } else if (this.isDraggingVScroll) {
      const deltaY = pos.y - this.dragStartY
      const scrollbar = this.drawer.getScrollbar().vertical
      const contentHeight = this.drawer.getTotalContentHeight()
      const viewHeight = this.drawer.getCanvasHeight() - 60 - 12
      const maxScroll = Math.max(0, contentHeight - viewHeight)

      const maxThumbY = scrollbar.height - scrollbar.thumbHeight
      const scrollRatio = maxScroll / maxThumbY
      const newScrollY = Math.max(
        0,
        Math.min(maxScroll, this.dragStartScrollY + deltaY * scrollRatio)
      )

      const viewport = this.drawer.getViewport()
      viewport.scrollY = newScrollY
      this.drawer.setViewport(viewport)
      this.drawer.draw()

      // 发布滚动事件
      this.context.emit('canvas:scroll', {
        scrollX: viewport.scrollX,
        scrollY: viewport.scrollY,
      })
    }
  }

  private handleMouseUp = () => {
    if (this.isDraggingHScroll) {
      this.isDraggingHScroll = false
      const scrollbar = this.drawer.getScrollbar()
      scrollbar.horizontal.isDragging = false
      this.drawer.draw()
    }

    if (this.isDraggingVScroll) {
      this.isDraggingVScroll = false
      const scrollbar = this.drawer.getScrollbar()
      scrollbar.vertical.isDragging = false
      this.drawer.draw()
    }
  }

  private handleMouseLeave = () => {
    this.handleMouseUp()
  }

  private handleWheel = (e: WheelEvent) => {
    e.preventDefault()

    const viewport = this.drawer.getViewport()
    const contentWidth = this.drawer.getTotalContentWidth()
    const contentHeight = this.drawer.getTotalContentHeight()
    const viewWidth = this.drawer.getCanvasWidth() - 150 - 12
    const viewHeight = this.drawer.getCanvasHeight() - 60 - 12

    const maxScrollX = Math.max(0, contentWidth - viewWidth)
    const maxScrollY = Math.max(0, contentHeight - viewHeight)

    // Shift + 滚轮 = 水平滚动
    if (e.shiftKey) {
      viewport.scrollX = Math.max(0, Math.min(maxScrollX, viewport.scrollX + e.deltaY))
    } else {
      viewport.scrollY = Math.max(0, Math.min(maxScrollY, viewport.scrollY + e.deltaY))
    }

    this.drawer.setViewport(viewport)
    this.drawer.draw()

    // 发布滚动事件，通知其他插件
    this.context.emit('canvas:scroll', {
      scrollX: viewport.scrollX,
      scrollY: viewport.scrollY,
    })
  }
}
